﻿using System.IO;
using CrmVersionhandlerTFS;
using Ionic.Zip;
using Microsoft.Crm.Sdk.Messages;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;

namespace CrmVersionhandler
{
    public class CrmVerionhandler : IPlugin
    {
        string customizationFolder;
        string tfsPath;
        string tfsServer;

        string username;
        string pass;
        string domain;

        public CrmVerionhandler(string unsecure, string secure)
        {
            if (!string.IsNullOrEmpty(unsecure))
            {
                Configuration m_config = new Configuration(unsecure);
                customizationFolder = m_config["CustomizationFolder"];
                tfsPath = m_config["TFSPath"];
                tfsServer = m_config["TFSServer"];
            }

            if (!string.IsNullOrEmpty(secure))
            {
                Configuration m_config = new Configuration(secure);
                username = m_config["Username"];
                pass = m_config["Password"];
                domain = m_config["Domain"];
            }
        }


        public void Execute(System.IServiceProvider serviceProvider)
        {
            #region Setup
            // Obtain the execution context from the service provider.
            IPluginExecutionContext context =
                (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));

            // Get a reference to the organization service.
            IOrganizationServiceFactory factory =
                (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
            IOrganizationService service = factory.CreateOrganizationService(context.UserId);

            if (!customizationFolder.EndsWith(context.OrganizationName))
                customizationFolder = Path.Combine(customizationFolder, context.OrganizationName);
            #endregion

            #region TFS Setup
            TFS tfs = new TFS(tfsServer, username, pass, domain);
            tfs.CreateWorkspace(tfsPath, customizationFolder);
            bool fileFound = tfs.Update(tfsPath, customizationFolder);
            #endregion

            #region get Solutions
            QueryExpression solutionsQuery = new QueryExpression("solution");
            solutionsQuery.Criteria.AddCondition("ismanaged", ConditionOperator.Equal, false);
            solutionsQuery.Criteria.AddCondition("isvisible", ConditionOperator.Equal, true);

            LinkEntity createdBy = new LinkEntity("solution", "systemuser", "createdby", "systemuserid", JoinOperator.Inner);
            createdBy.LinkCriteria.AddCondition("fullname", ConditionOperator.Equal, "SYSTEM");
            solutionsQuery.LinkEntities.Add(createdBy);
            
            solutionsQuery.ColumnSet.AddColumns("uniquename");
            EntityCollection solutionCollection = service.RetrieveMultiple(solutionsQuery);

            ExportSolutionRequest exportSolutionRequest = new ExportSolutionRequest();
            exportSolutionRequest.Managed = false;
            exportSolutionRequest.ExportAutoNumberingSettings = true;
            exportSolutionRequest.ExportCalendarSettings = true;
            exportSolutionRequest.ExportCustomizationSettings = true;
            exportSolutionRequest.ExportEmailTrackingSettings = true;
            exportSolutionRequest.ExportGeneralSettings = true;
            exportSolutionRequest.ExportIsvConfig = true;
            exportSolutionRequest.ExportMarketingSettings = true;
            exportSolutionRequest.ExportOutlookSynchronizationSettings = true;
            exportSolutionRequest.ExportRelationshipRoles = true;
            #endregion

            #region UnZip and save to disk
            foreach (Entity solution in solutionCollection.Entities)
            {
                string UniqueName = solution["uniquename"] as string;

                exportSolutionRequest.SolutionName = UniqueName;

                ExportSolutionResponse exportSolutionResponse = (ExportSolutionResponse)service.Execute(exportSolutionRequest);

                byte[] exportXml = exportSolutionResponse.ExportSolutionFile;
                string foldername = Path.Combine(customizationFolder, UniqueName);
                if (!Directory.Exists(foldername))
                {
                    Directory.CreateDirectory(foldername);
                }

                using (ZipFile zip1 = ZipFile.Read(exportXml, null))
                {
                    foreach (ZipEntry e in zip1)
                    {
                        e.Extract(foldername, ExtractExistingFileAction.OverwriteSilently);
                    }
                }
            }
            #endregion

            #region TFS Add and Checkin
            tfs.AddIfNotAlreadyInSvn(customizationFolder);
            tfs.Commit();
            #endregion
        }
    }
}
